﻿using System;
using System.Collections.Generic;
using System.Text;
using T.FAS.Runtime.Base.Entity;
using T.FAS.Runtime.DataAccess.Common;
using T.FAS.Runtime.DataAccess.Engine.ValidateChecker.Entity;
using T.FAS.Runtime.Metadata.Entity.DataModel;

namespace T.FAS.Runtime.DataAccess.Engine
{
    /// <summary>
    /// CDO运行时校验类
    /// </summary>
    public class CDOValidateChecker
    {
        public static ItemCheckResult Check(CompositeNodeObject cno, 
                                            CompositeNodeObjectElement element, 
                                            object inputValue, 
                                            bool isRef = false, 
                                            Dictionary<string, object> extinfo = null)
        {
            IValidateCheckItem checkitem = GetCheckItem(isRef);
            checkitem.CheckElement = ConvertTo(element, isRef, extinfo);
            checkitem.InputValue = inputValue;
            checkitem.ExtInfo = extinfo;
            return checkitem.Check();
        }

        /// <summary>
        /// 使用Element对应的DataColumn校验输入
        /// </summary>
        /// <param name="element"></param>
        /// <param name="isRef"></param>
        /// <param name="extinfo"></param>
        /// <returns></returns>
        private static IValidateCheckElement ConvertTo(CompositeNodeObjectElement element, bool isRef = false, Dictionary<string, object> extinfo = null)
        {
            var eleExtInfo = GetElementControlContext(extinfo, element);
            var checkElement = new ValidateCheckElement
            {
                DataType = element.DataType,
                DefaultValue = element.DefaultValue,    //默认值取Element中的默认值
                IsAllowNull = element.IsAllowNull,
                Length = element.Length,
                Precision = element.Precision,
                Name = element.Name,
                ValidateRule = element.DataColumn.ValidateRules,
                ElementExtInfo = eleExtInfo,
            };
            if (element.DataColumn.IsInternational
                && extinfo.ContainsKey(DACConst.CDO.IsI18NVal)
                && extinfo[DACConst.CDO.IsI18NVal] is bool isI18NVal
                && isI18NVal)
            {

                checkElement.IsAllowNull = true;
            }
            if (isRef)
            {
                var column = element.DataColumn;
                if (column != null && column.IsFkColumn)
                {
                    checkElement.IsReference = true;
                    checkElement.IsRefDataObject = column.IsRefDataObject;
                    checkElement.RefObjectID = column.RelatedDataObjectID;
                }
            }
            return checkElement;
        }

        private static Dictionary<string, object> GetElementControlContext(Dictionary<string, object> extinfo, CompositeNodeObjectElement element)
        {
            Dictionary<string, object> eleExtinfo = new Dictionary<string, object>();
            if (extinfo != null)
            {
                if (extinfo.ContainsKey("DbType"))
                {
                    var dbType = (DatabaseType)extinfo["DbType"];
                    //如果为string, SQLServer数据库且没有启用中文存储，需要按照字节判断输入值大小。
                    if (dbType == DatabaseType.SQLServer && element.DataType == DataType.String && !element.DataColumn.EnableUnicode)
                    {
                        eleExtinfo["ValidByteLength"] = true;
                        //当前字符集默认为GBK
                        eleExtinfo["Charset"] = "GBK";
                    }
                }
            }
            return eleExtinfo;
        }

        private static IValidateCheckItem GetCheckItem(bool isRef = false)
        {
            if (isRef && DACContextHelper.GetIsNeedCheckRefField())
                return new ValidateCheckRefItem();
            else
                return new ValidateCheckItem();
        }
    }
}